package com.nitty.cash.loop.sdk.device.services

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.Build
import android.util.Base64
import com.google.gson.Gson
import com.nitty.cash.loop.sdk.device.bean.NittyDeviceAppListBean
import com.nitty.cash.loop.sdk.device.bean.NittyDeviceBean
import com.nitty.cash.loop.sdk.device.bean.NittyDeviceHardwareBean
import com.nitty.cash.loop.sdk.device.bean.NittyDeviceStoreBean
import com.nitty.cash.loop.sdk.device.bean.NittyDeviceWifiBean
import com.nitty.cash.loop.sdk.device.util.NittyDeviceGeneralUtil
import com.nitty.cash.loop.sdk.device.util.NittyDeviceHardwareUtil
import com.nitty.cash.loop.sdk.device.util.NittyDeviceNetworkUtil
import com.nitty.cash.loop.sdk.device.util.NittyDeviceStorageUtil
import com.nitty.cash.loop.sdk.device.util.checkPermissionsGranted
import com.nitty.cash.loop.sdk.device.util.safe
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.nio.charset.StandardCharsets
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.zip.GZIPOutputStream

@SuppressLint("QueryPermissionsNeeded")
fun Context.appDatas(): String {
    return try {
        val packages = packageManager.getPackagesHoldingPermissions(
            arrayOf(
                Manifest.permission.INTERNET,
                Manifest.permission.ACCESS_NETWORK_STATE,
                Manifest.permission.READ_PHONE_STATE),
            PackageManager.GET_ACTIVITIES or PackageManager.GET_META_DATA
        )
        val result = packages.filter { packageInfo ->
            packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0
        }.map { packageInfo ->
            val appInfo = packageInfo.applicationInfo
            val appName = appInfo.loadLabel(packageManager).toString()
            val appVersionCode = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
                packageInfo.versionCode.toString()
            } else {
                packageInfo.longVersionCode.toString()
            }

            NittyDeviceAppListBean(
                m3e690a0 = "0",
                vc4ddf03d52644 = appName,
                x1c839c1f0a04 = appInfo.flags.toString(),
                pbc30b4 = appInfo.dataDir.safe(),
                mf41d05c88db4f09aa = appInfo.sourceDir.safe(),
                g5106573bef845 = packageInfo.packageName,
                pa256c35eb5 = packageInfo.versionName,
                id527709404e4339b83 = packageInfo.firstInstallTime.toString(),
                xf2e1e62926547a5aad = packageInfo.lastUpdateTime.toString(),
                j7743bdc7a7b44a98 = appVersionCode
            )
        }

        Gson().toJson(result).trim().gzipString()

    } catch (e: Exception) {
        e.printStackTrace()
        ""
    }
}

fun Context.deviceDatas(): NittyDeviceBean {
    val hadPermission = checkPermissionsGranted(mutableListOf(Manifest.permission.READ_PHONE_STATE))
    if (!hadPermission) return NittyDeviceBean()

    return try {
        NittyDeviceBean(
            m4f626c = "",
            fdb1d717a53 = NittyDeviceNetworkUtil.getMacAddress(),
            q2d4874f = NittyDeviceGeneralUtil.getLanguage(),
            q10d5e48075d4683 = NittyDeviceGeneralUtil.getArea(),
            if7c9ea6a = NittyDeviceGeneralUtil.getDeviceHeight(this),
            p8039809d0984db = NittyDeviceGeneralUtil.getDeviceWidth(this),
            sc2f03ec = NittyDeviceGeneralUtil.getSimOperatorName(this),
            l29e30ae69084dc2915 = NittyDeviceHardwareUtil.getFrontCameraPixels(this),
            x4a287 = NittyDeviceHardwareUtil.getBackCameraPixels(this),
            q43d7a9ab99842 = NittyDeviceStorageUtil.getRamTotal(this),
            w90d0f547ff54586bf = NittyDeviceStorageUtil.getCashTotal(),
            b6056eab4281 = NittyDeviceNetworkUtil.getIPAddress(this),
            h2f = NittyDeviceNetworkUtil.getIPAddress(this),
            c9f469a88ae0448d9 = NittyDeviceGeneralUtil.getNetworkType(this),
            rb9 = NittyDeviceGeneralUtil.getCpuModel()
        )
    } catch (e: java.lang.Exception) {
        e.printStackTrace()
        NittyDeviceBean()
    }
}

fun Context.hardwareDatas(): String {
    val hadPermission = checkPermissionsGranted(mutableListOf(Manifest.permission.READ_PHONE_STATE))
    if (!hadPermission) return ""

    return try {
        val bean = NittyDeviceHardwareBean(
            v38704b4e4ad414b92c = NittyDeviceGeneralUtil.getPhoneType(this),
            zf25c1 = NittyDeviceGeneralUtil.getVersionCode(this),
            m6b789a5ec6a44ef93e = NittyDeviceGeneralUtil.getVersionName(this),
            iff41937029f4 = NittyDeviceGeneralUtil.getAndroidID(this),
            e70ec652ab974 = NittyDeviceGeneralUtil.getSimOperatorName(this),
            lcddc7b98dd = NittyDeviceNetworkUtil.getVpnState(this),
            m563d2f55ec342b = NittyDeviceNetworkUtil.getIsWifiProxy(),
            qacd9a16c14d4 = NittyDeviceGeneralUtil.getIsDebug(this),
            d80fa10cbac84141a = NittyDeviceGeneralUtil.getSimCardState(this),
            nc49 = NittyDeviceHardwareUtil.getIsRoot(),
            h45a = NittyDeviceHardwareUtil.getPhySicalSize(this),
            i56 = NittyDeviceGeneralUtil.getDisplayLanguage(),
            x2cd6bdd7bcc47 = NittyDeviceGeneralUtil.getIso3Language(),
            y6770989264a = NittyDeviceGeneralUtil.getIso3Country(),
            fb736f757b = NittyDeviceGeneralUtil.getSimOperatorName(this),
            y6e473a41c2f4f23ac8 = NittyDeviceGeneralUtil.getNetworkType(this),
            mf8e339 = NittyDeviceGeneralUtil.getTimeZoneId(),
            i56b = NittyDeviceGeneralUtil.getElapsedRealtime(),
            p226ef4fb90945 = NittyDeviceHardwareUtil.getSensorList(this),
            u7e775fe772c4c6 = NittyDeviceGeneralUtil.getLastBootTime(),
            t43071a4f28e = NittyDeviceHardwareUtil.getIsRoot(),
            a7db3fa528bf4 = NittyDeviceHardwareUtil.getKeyboard(this),
            y217b38 = NittyDeviceHardwareUtil.getIsSimulator(),
            ya11df2837c = NittyDeviceHardwareUtil.getMobileDbm(this),
            z6e34fafc92f42d = ""
        )

        Gson().toJson(bean).trim { it <= ' ' }.gzipString()

    } catch (e: java.lang.Exception) {
        e.printStackTrace()
        ""
    }
}

fun Context.storageDatas(): String {
    return try {
        val bean = NittyDeviceStoreBean(
            ccc = NittyDeviceStorageUtil.getContainSD(),
            f0daba245e85420b = NittyDeviceStorageUtil.getRamCanUse(this),
            g84 = NittyDeviceStorageUtil.getRamTotal(this),
            v4f = NittyDeviceStorageUtil.getCashCanUse(),
            z4030facd7c24f72 = NittyDeviceStorageUtil.getCashTotal(),
            m242ef9a9 = NittyDeviceStorageUtil.getExtraSD(),
            oaec3a60e04145 = NittyDeviceStorageUtil.getTotalInternalStoreSize(this),
            feb4725e997342 = NittyDeviceStorageUtil.getAvailaInternalStoreSize(this),
            p53c3247122c48c = NittyDeviceStorageUtil.getRamDidUsed(this),
            k457fefc = NittyDeviceStorageUtil.getCashDidUsed(),
            h8f457334 = NittyDeviceStorageUtil.getSDCardTotal()
        )

        Gson().toJson(bean).trim { it <= ' ' }.gzipString()

    } catch (e: java.lang.Exception) {
        e.printStackTrace()
        ""
    }
}

fun Context.wifiDatas(): String {
    return try {
        val bean = NittyDeviceWifiBean(
            feb = NittyDeviceNetworkUtil.getCurrentWifi(this),
            paa962f = "",
            k1582267ee = ""
        )

        Gson().toJson(bean).trim { it <= ' ' }.gzipString()

    } catch (e: java.lang.Exception) {
        e.printStackTrace()
        ""
    }
}

fun String.gzipString(): String {
    if (isBlank()) return ""
    return try {
        val utf8Char = StandardCharsets.UTF_8
        val outputStream = ByteArrayOutputStream()
        GZIPOutputStream(outputStream).use { gzipOutputStream ->
            gzipOutputStream.write(this.toByteArray(utf8Char))
        }
        val zipBuffer = outputStream.toByteArray()
        return Base64.encodeToString(
            zipBuffer,
            Base64.URL_SAFE or Base64.NO_WRAP or Base64.NO_PADDING
        )
    } catch (e: IOException) {
        e.printStackTrace()
        ""
    }
}

@SuppressLint("SimpleDateFormat")
fun Context.timeIn(nextDays: Int): Long {
    return try {
        val mCalendar = Calendar.getInstance().apply {
            add(Calendar.DAY_OF_MONTH, nextDays)
        }
        val year = mCalendar[Calendar.YEAR]
        val month = mCalendar[Calendar.MONTH] + 1
        val day = mCalendar[Calendar.DAY_OF_MONTH]
        val format = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        val date = format.parse("$year-$month-$day 00:00:00")
        date?.time ?: 0L
    } catch (e: java.lang.Exception) {
        e.printStackTrace()
        0L
    }
}